从 C 语言中的管道读取数据 您所在的位置:网站首页 read函数 c语言 从 C 语言中的管道读取数据

从 C 语言中的管道读取数据

2023-04-22 17:21| 来源: 网络整理| 查看: 265

使用 pipe 和 read 系统调用在 C 语言中从管道中读取数据 在 C 语言中使用 while 循环从管道中读取数据

本文将演示有关如何从 C 语言中的管道读取的多种方法。

使用 pipe 和 read 系统调用在 C 语言中从管道中读取数据

管道是基于 UNIX 的系统中的进程间通信(IPC)原语的变体之一。它提供了一个单向通信通道,即两个进程之间的字节流,并且数据在一个方向上顺序移动。pipe 系统调用用于创建管道并获取其读取和写入端的文件描述符。注意,我们可以使用普通的 I/O 函数 read 和 write 对管道描述符进行操作。pipe 系统调用采用包含两个元素的 int 数组,成功调用将返回两个文件描述符,分别表示第一个-读取和第二个-写入结束。请注意,写入管道的数据会在内核中进行缓冲,直到读取器检索到给定的字节为止。

在下面的示例中,我们演示了在父进程和子进程之间进行通信的管道的基本用法。首先,我们创建一个管道并将其描述符存储在 pipe_fd 数组中。接下来,我们在 switch 语句表达式中调用 fork,并在情况 0 下包含子进程的代码块。另一方面,default 情况将由父进程执行。

请注意,父级将写入从命令行参数中检索到的字符串,然后等待子级终止。同时,子进程从管道读取,并将读取的字节打印到控制台。子进程和父进程都关闭管道的一端,因为子进程继承了 fork 上父进程的文件描述符。最后,在读取发送的字节之后,子进程关闭管道的读取端,并以 exit 调用终止。

#include #include #include #include #include enum {BUF_SIZE = 4096}; int main(int argc, char *argv[]) { int pipe_fd[2]; char buf[BUF_SIZE]; ssize_t numRead; if (argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); exit(EXIT_FAILURE); } if (pipe(pipe_fd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } switch (fork()) { case -1: perror("fork"); exit(EXIT_FAILURE); case 0: if (close(pipe_fd[1]) == -1) { perror("close - parent"); exit(EXIT_FAILURE); } sleep(3); numRead = read(pipe_fd[0], buf, BUF_SIZE); write(STDOUT_FILENO, buf, numRead); write(STDOUT_FILENO, "\n", 1); if (close(pipe_fd[0]) == -1) { perror("close"); exit(EXIT_FAILURE); } _exit(EXIT_SUCCESS); default: if (close(pipe_fd[0]) == -1) { perror("close - parent"); exit(EXIT_FAILURE); } if (write(pipe_fd[1], argv[1], strlen(argv[1])) != strlen(argv[1])) { perror("write - partial/failed write"); exit(EXIT_FAILURE); } if (close(pipe_fd[1]) == -1) { perror("close"); exit(EXIT_FAILURE); } wait(NULL); exit(EXIT_SUCCESS); } } 在 C 语言中使用 while 循环从管道中读取数据

先前的示例代码有一个欺骗性的错误,该错误可能导致子进程中的部分读取。read 调用返回的数据可能少于管道中的数据,因此在此示例中调用一个 read 调用将是错误的。幸运的是,read 函数返回读取的字节数,我们可以实现一个循环,以用尽管道中的数据,如下一个代码示例所示。请注意,管道具有固定的容量,如果达到最大值,则写操作将阻塞,直到读取器检索到一些数据为止。

#include #include #include #include #include enum {BUF_SIZE = 4096}; int main(int argc, char *argv[]) { int pipe_fd[2]; char buf[BUF_SIZE]; ssize_t numRead; if (argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); exit(EXIT_FAILURE); } if (pipe(pipe_fd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } switch (fork()) { case -1: perror("fork"); exit(EXIT_FAILURE); case 0: if (close(pipe_fd[1]) == -1) { perror("close - parent"); exit(EXIT_FAILURE); } while (1) { numRead = read(pipe_fd[0], buf, BUF_SIZE); if (numRead == -1) { perror("read"); exit(EXIT_FAILURE); } if (numRead == 0) break; if (write(STDOUT_FILENO, buf, numRead) != numRead){ perror("write - partial/failed write"); exit(EXIT_FAILURE); } } write(STDOUT_FILENO, "\n", 1); if (close(pipe_fd[0]) == -1) { perror("close"); exit(EXIT_FAILURE); } _exit(EXIT_SUCCESS); default: if (close(pipe_fd[0]) == -1) { perror("close - parent"); exit(EXIT_FAILURE); } if (write(pipe_fd[1], argv[1], strlen(argv[1])) != strlen(argv[1])) { perror("write - partial/failed write"); exit(EXIT_FAILURE); } if (close(pipe_fd[1]) == -1) { perror("close"); exit(EXIT_FAILURE); } wait(NULL); exit(EXIT_SUCCESS); } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有